home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Archivers / CompDisk / DecompSub.c < prev    next >
C/C++ Source or Header  |  1996-09-26  |  4KB  |  249 lines

  1. long __regargs    memread(char *,long);
  2. long        compinit(void);
  3. void        compexit(void);
  4. long __regargs    decompfiles(char *,long,char *,long);
  5. void __regargs    decompress(char *,long);
  6. long        getcode(void);
  7.  
  8. #define BITS 12
  9.  
  10. #if BITS == 16
  11. #    define HSIZE    69001 
  12. #endif
  13. #if BITS == 15
  14. #    define HSIZE    35023 
  15. #endif
  16. #if BITS == 14
  17. #    define HSIZE    18013 
  18. #endif
  19. #if BITS == 13
  20. #    define HSIZE    9001 
  21. #endif
  22. #if BITS <= 12
  23. #    define HSIZE    5003 
  24. #endif
  25.  
  26. #define BLOCK_MASK    0x80
  27. #define INIT_BITS    9
  28.  
  29. #define MAXCODE(n_bits) ((1 << (n_bits)) - 1)
  30.  
  31. #define tab_prefixof(i) codetab[i]
  32. #define tab_suffixof(i) ((unsigned char *)(htab))[i]
  33. #define de_stack    ((unsigned char *)&tab_suffixof(1<<BITS))
  34.  
  35. #define FIRST    257 
  36. #define CLEAR    256 
  37.  
  38. const unsigned char rmask[9] = {0x00,0x01,0x03,0x07,0x0F,0x1F,0x3F,0x7F,0xFF};
  39.  
  40. long        *htab;
  41. unsigned short    *codetab;
  42.  
  43. long buffsize;
  44. char *buffstart;
  45.  
  46. long free_ent,block_compress,clear_flg,n_bits,maxcode,maxmaxcode;
  47.  
  48. long __regargs
  49. memread(mem,size)
  50. register char *mem;
  51. register long size;
  52. {
  53.     register long bytesread = 0;
  54.  
  55.     while(size-- > 0)
  56.     {
  57.         if(buffsize-- > 0)
  58.         {
  59.             *mem++ = *buffstart++;
  60.             bytesread++;
  61.         }
  62.         else
  63.             return(bytesread);
  64.     }
  65.  
  66.     return(bytesread);
  67. }
  68.  
  69. void __regargs
  70. decompress(sect,watermark)
  71. register char *sect;
  72. register long watermark;
  73. {
  74.     unsigned char *stackp;
  75.     long finchar,code,oldcode,incode,reallywritten = 0;
  76.  
  77.     maxmaxcode = 1 << BITS;
  78.     clear_flg = 0;
  79.     block_compress = BLOCK_MASK;
  80.  
  81.     maxcode = MAXCODE(n_bits = INIT_BITS);
  82.  
  83.     for(code = 255 ; code >= 0 ; code--)
  84.     {
  85.         tab_prefixof(code) = 0;
  86.         tab_suffixof(code) = (unsigned char) code;
  87.     }
  88.  
  89.     free_ent = ((block_compress) ? FIRST : 256);
  90.     finchar = oldcode = getcode();
  91.  
  92.     if(oldcode == -1)
  93.         return;
  94.  
  95.     if(reallywritten++ < watermark)
  96.         *sect++ = finchar;
  97.  
  98.     stackp = de_stack;
  99.  
  100.     while((code = getcode()) > -1)
  101.     {
  102.         if((code == CLEAR) && block_compress)
  103.         {
  104.             for(code = 255 ; code >= 0 ; code--)
  105.                 tab_prefixof(code) = 0;
  106.  
  107.             clear_flg = 1;
  108.             free_ent = FIRST - 1;
  109.  
  110.             if((code = getcode()) == -1)
  111.                 break;
  112.         }
  113.  
  114.         incode = code;
  115.  
  116.         if(code >= free_ent)
  117.         {
  118.             *stackp++ = finchar;
  119.             code = oldcode;
  120.         }
  121.  
  122.         while(code >= 256)
  123.         {
  124.             *stackp++ = tab_suffixof(code);
  125.             code = tab_prefixof(code);
  126.         }
  127.  
  128.         *stackp++ = finchar = tab_suffixof(code);
  129.  
  130.         do
  131.         {
  132.             if(reallywritten++ < watermark)
  133.                 *sect++ = *--stackp;
  134.         }
  135.         while(stackp > de_stack);
  136.  
  137.         if((code = free_ent) < maxmaxcode)
  138.         {
  139.             tab_prefixof(code) = (unsigned short)oldcode;
  140.             tab_suffixof(code) = finchar;
  141.             free_ent = code + 1;
  142.         }
  143.  
  144.         oldcode = incode;
  145.     }
  146. }
  147.  
  148. long
  149. getcode()
  150. {
  151.     static long offset = 0,size = 0;
  152.     static unsigned char buf[BITS];
  153.  
  154.     long r_off,bits,code;
  155.     register unsigned char *bp = buf;
  156.  
  157.     if(clear_flg > 0 || offset >= size || free_ent > maxcode)
  158.     {
  159.         if(free_ent > maxcode)
  160.         {
  161.             n_bits++;
  162.  
  163.             if(n_bits == BITS)
  164.                 maxcode = maxmaxcode;
  165.             else
  166.                 maxcode = MAXCODE(n_bits);
  167.         }
  168.  
  169.         if(clear_flg > 0)
  170.         {
  171.             maxcode = MAXCODE(n_bits = INIT_BITS);
  172.             clear_flg = 0;
  173.         }
  174.  
  175.         size = memread(buf,n_bits);
  176.  
  177.         if(size <= 0)
  178.             return(-1);
  179.  
  180.         offset = 0;
  181.  
  182.         size = (size << 3) - (n_bits - 1);
  183.     }
  184.  
  185.     r_off = offset;
  186.     bits = n_bits;
  187.     bp += (r_off >> 3);
  188.     r_off &= 7;
  189.     code = (*bp++ >> r_off);
  190.     bits -= (8 - r_off);
  191.     r_off = 8 - r_off;
  192.  
  193.     if(bits >= 8)
  194.     {
  195.         code |= *bp++ << r_off;
  196.         r_off += 8;
  197.         bits -= 8;
  198.     }
  199.  
  200.     code |= (*bp & rmask[bits]) << r_off;
  201.     offset += n_bits;
  202.  
  203.     return(code);
  204. }
  205.  
  206. long
  207. compinit()
  208. {
  209.     if(!(htab = (long *)AllocMem(HSIZE * sizeof(long),0)))
  210.         return(FALSE);
  211.  
  212.     if(!(codetab = (unsigned short *)AllocMem(HSIZE * sizeof(unsigned short),0)))
  213.     {
  214.         FreeMem(htab,HSIZE * sizeof(long));
  215.  
  216.         htab = NULL;
  217.  
  218.         return(FALSE);
  219.     }
  220.  
  221.     maxmaxcode = 1 << BITS;
  222.  
  223.     return(TRUE);
  224. }
  225.  
  226. void
  227. compexit()
  228. {
  229.     if(htab)
  230.         FreeMem(htab,HSIZE * sizeof(long));
  231.  
  232.     if(codetab)
  233.         FreeMem(codetab,HSIZE * sizeof(unsigned short));
  234.  
  235.     htab = NULL;
  236.     codetab = NULL;
  237. }
  238.  
  239. long __regargs
  240. decompfiles(from,readsize,to,maxsize)
  241. char *from,*to;
  242. long readsize,maxsize;
  243. {
  244.     buffstart    = from;
  245.     buffsize    = readsize;
  246.  
  247.     decompress(to,maxsize);
  248. }
  249.